package cn.infozr.api.client;

import java.util.List;
import java.util.ArrayList;
import java.util.UUID;

import cn.infozr.api.util.MD5Util;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 药品库存信息上传接口客户端
 * 用于测试 http://IP:端口/ygydapi/v1/uploadDrugInvinfo 接口
 */
public class DrugInventoryUploadApiClient extends BaseClient {
    

    
    /**
     * 药品库存信息数据项
     */
    public static class DrugInventoryItem {
        private String ypwybsm;  // 药品唯一标识码
        private String yppzwh;  // 完整的药品批准文号
        private Double sl;       // 数量（按最小计价包装单位统计，保留2位小数）
        private Integer pdlx;    // 盘点类型：1初始化 2定期盘点
        
        // Getters and Setters
        public String getYpwybsm() { return ypwybsm; }
        public void setYpwybsm(String ypwybsm) { this.ypwybsm = ypwybsm; }
        
        public Double getSl() { return sl; }
        public void setSl(Double sl) { this.sl = sl; }
        
        public Integer getPdlx() { return pdlx; }
        public void setPdlx(Integer pdlx) { this.pdlx = pdlx; }

        public String getYppzwh() {
            return yppzwh;
        }

        public void setYppzwh(String yppzwh) {
            this.yppzwh = yppzwh;
        }
    }
    
    /**
     * 药品库存信息上传请求参数类
     */
    public static class DrugInventoryUploadRequest {
        private String appId;
        private String timestamp;
        private String reqId;
        private String uscc;
        private String data;
        private String sign;
        
        // 构造函数
        public DrugInventoryUploadRequest() {
            this.timestamp = String.valueOf(System.currentTimeMillis());
            this.reqId = UUID.randomUUID().toString().replace("-", "");
            //this.data = new ArrayList<>();
        }
        
        // Getters and Setters
        public String getAppId() { return appId; }
        public void setAppId(String appId) { this.appId = appId; }
        
        public String getTimestamp() { return timestamp; }
        public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
        
        public String getReqId() { return reqId; }
        public void setReqId(String reqId) { this.reqId = reqId; }
        
        public String getUscc() { return uscc; }
        public void setUscc(String uscc) { this.uscc = uscc; }
        
        public String getData() { return data; }
        public void setData(String data) { this.data = data; }
        
        public String getSign() { return sign; }
        public void setSign(String sign) { this.sign = sign; }
    }
    
    /**
     * 生成数据签名
     * @param request 请求参数对象
     * @return 签名字符串
     * @throws Exception 加密异常
     */
    protected String generateSign(DrugInventoryUploadRequest request) throws Exception {
        // 按照字段名的字典序拼接参数
        java.util.TreeMap<String, String> params = new java.util.TreeMap<>();
        params.put("appId", request.getAppId());
        params.put("reqId", request.getReqId());
        params.put("timestamp", request.getTimestamp());
        
        if (request.getUscc() != null && !request.getUscc().isEmpty()) {
            params.put("uscc", request.getUscc());
        }
        if (request.getData() != null && !request.getData().isEmpty()) {
            params.put("data", request.getData());
        }
        
        return cn.infozr.api.util.SM3SignatureUtil.generateSignature(params, SECRET_KEY);
    }
    
    /**
     * 调用药品库存信息上传接口
     * @param uscc 药店18位统一社会信用代码
     * @param data 药品库存信息数据列表
     * @return 接口响应结果
     * @throws Exception 网络或解析异常
     */
    public String uploadDrugInventory(String uscc, List<DrugInventoryItem> data) throws Exception {
        // 构造请求参数
        DrugInventoryUploadRequest request = new DrugInventoryUploadRequest();
        request.setAppId(APP_ID);
        request.setTimestamp(String.valueOf(System.currentTimeMillis()));
        request.setUscc(uscc);
        if (data != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            String dataJson = objectMapper.writeValueAsString(data);
            request.setData(dataJson);
            // 传递相同的reqId到服务器，服务器会忽略本次请求 （为防止网格中断导致数据重复上传,建议该值传MD5(数据)）
            String reqId = MD5Util.getMD5(dataJson);
            request.setReqId(reqId);
        }
        
        // 生成签名
        request.setSign(generateSign(request));
        
        // 发送POST请求
        return sendPostRequest(DRUG_INVENTORY_API_URL, request);
    }
    
    /**
     * 发送POST请求（重写父类方法以适应新的请求类型）
     * @param url 请求地址
     * @param request 请求参数对象
     * @return 响应结果
     * @throws Exception 网络异常
     */
    protected String sendPostRequest(String url, DrugInventoryUploadRequest request) throws Exception {
        java.net.URL obj = new java.net.URL(url);
        java.net.HttpURLConnection con = (java.net.HttpURLConnection) obj.openConnection();

        // 设置请求方法和请求头
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("Accept", "application/json");
        con.setDoOutput(true);

        // 序列化请求参数，过滤空值
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL);
        String jsonInputString = objectMapper.writeValueAsString(request);
        System.out.println("请求参数: " + jsonInputString);
        
        // 发送请求
        try(java.io.OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        // 读取响应
        try(java.io.BufferedReader br = new java.io.BufferedReader(
                new java.io.InputStreamReader(con.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine = null;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();
        }
    }
    
    /**
     * 解析并打印上传结果
     * @param jsonResponse JSON响应字符串
     * @throws Exception 解析异常
     */
    public void parseAndPrintUploadResult(String jsonResponse) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        com.fasterxml.jackson.databind.JsonNode rootNode = objectMapper.readTree(jsonResponse);
        
        System.out.println("接口响应:");
        System.out.println("状态码: " + (rootNode.has("code") ? rootNode.get("code").asText() : "无"));
        System.out.println("消息提示: " + (rootNode.has("msg") ? rootNode.get("msg").asText() : "无"));
        System.out.println("请求ID: " + (rootNode.has("reqId") ? rootNode.get("reqId").asText() : "无"));
    }
    
    /**
     * 主方法 - 测试接口调用
     */
    public static void main(String[] args) {
        try {
            DrugInventoryUploadApiClient client = new DrugInventoryUploadApiClient();
            
            // 构造测试数据
            List<DrugInventoryItem> data = new ArrayList<>();
            
//            DrugInventoryItem item1 = new DrugInventoryItem();
//            item1.setYpwybsm("1021562371750417525");
//            item1.setYppzwh("国药准字H20063830");
//            item1.setSl(100.90);
//            item1.setPdlx(2);
//            data.add(item1);
//
//            DrugInventoryItem item2 = new DrugInventoryItem();
//            item2.setYpwybsm("1346857632788601987");
//            item2.setYppzwh("国药准字H2021005377777");
//            item2.setSl(50.68);
//            item2.setPdlx(2);
//            data.add(item2);

            DrugInventoryItem item3 = new DrugInventoryItem();
            item3.setYpwybsm("1021285934992024983");
            item3.setYppzwh("国药准字Z4402031477777");
            item3.setSl(50.68);
            item3.setPdlx(2);
            data.add(item3);
//            DrugInventoryItem item4 = new DrugInventoryItem();
//            item4.setYpwybsm("1346959992064146887");
//            item4.setYppzwh("国药准字Z20054063");
//            item4.setSl(50.68);
//            item4.setPdlx(1);
//            data.add(item4);

            // 测试调用接口
            String result = client.uploadDrugInventory(uscc, data);
            
            // 解析并打印结果
            client.parseAndPrintUploadResult(result);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}